#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "persondao.h"
#include "logindialog.h"
#include <QLabel>
#include <QPixmap>
#include <QFile>
#include <QMessageBox>
#include <time.h>
#include <stdlib.h>
#include <ExcelHelper.h>

#define WIDTH 6

MainWindow::MainWindow(QString subject,int num,QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    seatNum = num;
    QString msg = QString("考试科目： %1  考试人数： %2").arg(subject).arg(num);
    ui->label_msg->setText(msg);

    initSeats();
    initOpencv();
    startTimer(50);
    srand(time(0));//初始化随机种子
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::initSeats()
{
    int count = 0;
    for (int y = 0;y < seatNum;y++) {
        for (int x = 0;x < WIDTH;x++) {
            QLabel *seat = new QLabel(this) ;//创建一个座位
            seat->setObjectName("None");//设置座位的名字为空，代表没有人
            seat->setMaximumSize(60,60);//设置座位最大大小
            QPixmap pm(":/avatar.png");//创建空座位的图像
            seat->setPixmap(pm);//将空座位的图像设置到label中显示
            seat->setFrameShape(QFrame::Box);//设置为有边框的图像
            seat->setScaledContents(true);//设置为可调整大小
            ui->gridLayout->addWidget(seat,y,x,1,1);//将头像放入gridlayout控件中

            if(++count == seatNum)
            {
                return;
            }
        }
    }



}

void MainWindow::initOpencv()
{
    cc.load("E:/worktools/opencv/opencv3.4-install/install/etc/haarcascades/haarcascade_frontalface_alt2.xml");
    QFile file("face.xml");
    if(file.exists())
    {
        faceRecognizer = FaceRecognizer::load<LBPHFaceRecognizer>("face.xml");
    }
    else
    {
        faceRecognizer = LBPHFaceRecognizer::create();
    }
    vc.open(0);
    faceRecognizer->setThreshold(100);//设置人脸识别器阈值
}
void MainWindow::timerEvent(QTimerEvent *e)
{
    vc>>frame;
    flip(frame,frame,1);
    findFace();
    showFace();
}

void MainWindow::showFace()
{
    Mat rgb;
    cvtColor(frame,rgb,COLOR_BGR2RGB);
    QImage img(rgb.data,rgb.cols,rgb.rows,rgb.cols*rgb.channels(),QImage::Format_RGB888);
    ui->label_face->setPixmap(QPixmap::fromImage(img));
    ui->label_face->resize(QSize(rgb.cols,rgb.rows));
}

void MainWindow::findFace()
{
    Mat gary;
    cvtColor(frame,gary,COLOR_BGR2GRAY);
    cc.detectMultiScale(gary,faces,1.1,3,0,Size(150,150),Size(500,500));
    if(faces.size() > 0)
    {
        rectangle(frame,faces[0],Scalar(0,0,255));
    }
}

void MainWindow::randSeat(QString name, int id)
{
    QLabel *label;
    int x,y;
    do{
        int index = rand()%seatNum;//随机一个座位的index
        x = index % WIDTH;
        y = index / WIDTH;
        QLayoutItem *item = ui->gridLayout->itemAtPosition(y,x);
        QWidget *widget = item->widget();
        label = dynamic_cast<QLabel*>(widget);//强制类型转换,找到对应的label位置
    }while(label->objectName() == "Person");

    label->setObjectName("Person");//将控件名字改为有人
    Mat face = frame(faces[0]);
    Mat rgb;
    cvtColor(face,rgb,COLOR_BGR2RGB);
    QImage img(rgb.data,rgb.cols,rgb.rows,rgb.cols*rgb.channels(),QImage::Format_RGB888);
    label->setPixmap(QPixmap::fromImage(img));

    Person p;//创建学生对象
    p.name = name;
    p.x = x;
    p.y = y;
    person[id] = p;//插入考生和座位的信息


}


void MainWindow::on_pushButton_choose_clicked()
{
    QString name = ui->lineEdit_name->text();//获取考生名字
    if(name.isEmpty() || faces.size() == 0)
    {
        QMessageBox::warning(this,"警告","考生名字为空或未识别到人脸");
        return;
    }
    PersonData pd;
    pd.name = name;
    PersonDao::getInstance()->insertPerson(pd);//将输入的考生名字插入到数据库中
    int id = PersonDao::getInstance()->getLabel();//获取考生id

    Mat face = frame(faces[0]);//获取考生的人脸图像
    cvtColor(face,face,COLOR_BGR2GRAY);
    cv::resize(face,face,Size(100,100));

    vector<Mat> stuFace;
    vector<int> label;

    stuFace.push_back(face);
    label.push_back(id);

    faceRecognizer->update(stuFace,label);//更新人脸识别器
    faceRecognizer->save("face.xml");//保存人脸识别器
    QMessageBox::information(this,"提示","恭喜你成功录入，可以开始考试了");

    randSeat(name,id);


}

void MainWindow::on_pushButton_exit_clicked()
{
    if(faces.size() == 0||faceRecognizer.empty())
    {
         QMessageBox::warning(this,"警告","未识别人脸，人脸为空");
    }
    Mat face = frame(faces[0]);
    cvtColor(face,face,COLOR_BGR2GRAY);
    cv::resize(face,face,Size(100,100));
    int label;
    double confidance;
    faceRecognizer->predict(face,label,confidance);//对当前人脸进行人脸识别
    if(person.count(label) == 0)
    {
        QMessageBox::warning(this,"警告","请不要冒名顶替！！！");
        return;
    }

    Person p = person[label];//通过人脸识别结果返回的label  找到对应的人
    QLayoutItem *item = ui->gridLayout->itemAtPosition(p.y,p.x);
    QWidget *widget = item->widget();
    QLabel *lb = dynamic_cast<QLabel*>(widget);
    lb->setPixmap(QPixmap(":/avatar.png"));
    lb->setObjectName("None");
    PersonDao::getInstance()->updateInfo(label);
    QMessageBox::information(this,"提示",QString("%1考生已离开").arg(p.name));


}

void MainWindow::on_pushButton_output_clicked()
{
    QString filepath = ui->lineEdit_excel->text();
    if(filepath.isEmpty())
    {
        QMessageBox::warning(this,"警告","没有填写要保存的路径");
        return;
    }
    vector<PersonData> pd;
    PersonDao::getInstance()->selectInfo(pd);

    ExcelHelper eh;
    eh.open(filepath);
    eh.addInfos(pd);
    eh.close();
    QMessageBox::information(this,"提示","保存文件成功");
}
